using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using flickr.api.communication;

namespace flickr.api
{
    [Flags]
	public enum PhotoSearchExtras
	{
		None = 0,
		License = 1,
		DateUploaded = 2,
		DateTaken = 4,
		OwnerName = 8,
		IconServer = 16
	}

	[Serializable]
	public class Photos : FlickrObject
	{
	    public Photos() : base() {}
	    public Photos(FlickrConnection connection) : base(connection){}
	    
	    [XmlElement("photo", Form=XmlSchemaForm.Unqualified)]
		public PhotoCollection PhotoCollection = new PhotoCollection();

	    [XmlAttribute("page", Form=XmlSchemaForm.Unqualified)]
		public long PageNumber;

	    [XmlAttribute("pages", Form=XmlSchemaForm.Unqualified)]
		public long TotalPages;

	    [XmlAttribute("perpage", Form=XmlSchemaForm.Unqualified)]
		public long PhotosPerPage;

	    [XmlAttribute("total", Form=XmlSchemaForm.Unqualified)]
		public long TotalPhotos;

        public void addTags(int photoId, string[] tags)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            request.AddParameter(FlickrParameterType.Tags, tags);

            Send(request);
        }

        public XmlElement[] getAllContexts(int photoId)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);

            return Send(request).AllElements;
        }
       
        public Photos getContactsPhotos()
        {
            return getContactsPhotos(10, false, false, false);
        }

        public Photos getContactsPhotos(int count, bool justFriends, bool singlePhoto, bool includeSelf)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.Count, count);
            request.AddParameter(FlickrParameterType.JustFriends, justFriends);
            request.AddParameter(FlickrParameterType.SinglePhoto, singlePhoto);
            request.AddParameter(FlickrParameterType.IncludeSelf, includeSelf);

            return Send(request).Photos;
        }
        
        public Photos getContactsPublicPhotos(int count, bool justFriends, bool singlePhoto, bool includeSelf, params string[] extras)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.Count, count);
            request.AddParameter(FlickrParameterType.JustFriends, justFriends);
            request.AddParameter(FlickrParameterType.SinglePhoto, singlePhoto);
            request.AddParameter(FlickrParameterType.IncludeSelf, includeSelf);

            return Send(request).Photos;
        }
	    
        public void getContext(int photoId)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            
            //Send(request).
        }
	    
        public PhotoCounts getCounts(DateTime[] dates, DateTime[] datesTaken)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.Dates, dates.ToString());
            request.AddParameter(FlickrParameterType.DatesTaken, dates.ToString());

            return Send(request).PhotoCounts;
        }
	    
//        public ExifPhoto getExif(string photoId, string secret)
//        {
//            FlickrRequest request = CreateRequest();
//            request.AddParameter(FlickrParameterType.PhotoId, photoId);
//            request.AddParameter(FlickrParameterType.Secret, secret);
//            
//            return Send(request).Photo.Photo.;
//        }

        public PhotoInfo getInfo(string photoId, string secret)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            request.AddParameter(FlickrParameterType.Secret, secret);

            return Send(request).Photo;
        }
	    
        public Photos getNotInSet(DateTime minUploadDate, DateTime maxUploadDate, DateTime minTakenDate, DateTime maxTakenDate, string extras, int perPage, int page)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.MinUploadDate, minUploadDate);
            request.AddParameter(FlickrParameterType.MaxUploadDate, maxUploadDate);
            request.AddParameter(FlickrParameterType.MinTakenDate, minTakenDate);
            request.AddParameter(FlickrParameterType.MaxTakenDate, maxTakenDate);
            request.AddParameter(FlickrParameterType.PerPage, perPage);
            request.AddParameter(FlickrParameterType.Page, page);
            return Send(request).Photos;
        }
	    
        public PhotoPermissions getPerms(int photoId)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            return Send(request).PhotoPermissions;
        }

        public Photos getRecent()
        {
            return getRecent(long.MinValue, long.MinValue);
        }

        public Photos getRecent(long photosPerPage, long selectedPage)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PerPage, photosPerPage);
            request.AddParameter(FlickrParameterType.Page, selectedPage);

            return Send(request).Photos;
        }

        public Sizes getSizes(string photoId)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            
            return Send(request).Sizes;
        }

	    public Photos getUntagged(DateTime minUploadDate, DateTime maxUploadDate, DateTime minDateTaken, DateTime maxDateTaken,
            PrivateFilter privacyFilter, PhotoSearchExtras extras, int perPage, int page)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.MinUploadDate, minUploadDate);
            request.AddParameter(FlickrParameterType.MaxUploadDate, maxUploadDate);
            request.AddParameter(FlickrParameterType.MinTakenDate, minDateTaken);
            request.AddParameter(FlickrParameterType.MaxTakenDate, maxDateTaken);
            request.AddParameter(FlickrParameterType.PrivacyFilter, privacyFilter);
            request.AddParameter(FlickrParameterType.Extras, extras);
            request.AddParameter(FlickrParameterType.PerPage, perPage);
            request.AddParameter(FlickrParameterType.Page, page);

            return Send(request).Photos;
        }
	    
        public void removeTag(string tagId)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.TagId, tagId);

            Send(request);
        }
	    
        public Photos search(string userId, string[] tags, string tagMode, string text, DateTime minUploadDate, DateTime maxUploadDate, DateTime minDateTaken, DateTime maxDateTaken, License license, string sort, PrivateFilter filter, PhotoSearchExtras extras, int perPage, int page)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.UserId, userId);
            request.AddParameter(FlickrParameterType.Tags, tags);
            request.AddParameter(FlickrParameterType.TagMode, tagMode);
            request.AddParameter(FlickrParameterType.Text, text);
            request.AddParameter(FlickrParameterType.MinUploadDate, minUploadDate);
            request.AddParameter(FlickrParameterType.MaxUploadDate, maxUploadDate);
            request.AddParameter(FlickrParameterType.MinTakenDate, minDateTaken);
            request.AddParameter(FlickrParameterType.MaxTakenDate, maxDateTaken);
            request.AddParameter(FlickrParameterType.License, license);
            request.AddParameter(FlickrParameterType.Extras, extras);
            request.AddParameter(FlickrParameterType.PerPage, perPage);
            request.AddParameter(FlickrParameterType.Page, page);
            request.AddParameter(FlickrParameterType.Sort, sort);

            return Send(request).Photos;
        }
        
	    public enum PhotoGranularity
	    {
	        seconds = 0,
	        month = 4,
	        year = 6
	    }
        public void setDates(string photoId, DateTime datePosted, DateTime dateTaken, PhotoGranularity granularity)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            request.AddParameter(FlickrParameterType.DatePosted, datePosted);
            request.AddParameter(FlickrParameterType.DateTaken, dateTaken);
            request.AddParameter(FlickrParameterType.DateTakenGranularity, granularity);

            Send(request);
        }
	    
        public void setMeta(string photoId, string title, string description)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            request.AddParameter(FlickrParameterType.Title, title);
            request.AddParameter(FlickrParameterType.Description, description);
            
            Send(request);
        }
	    
        public void setPerms(string photoId, bool isPublic, bool isFriend, bool isFamily, PermissionComment commitPerms, PermissionAddMeta metaDataPerms)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            request.AddParameter(FlickrParameterType.IsPublic, isPublic);
            request.AddParameter(FlickrParameterType.IsFriend, isFriend);
            request.AddParameter(FlickrParameterType.IsFamily, isFamily);
            request.AddParameter(FlickrParameterType.PermComment, commitPerms);
            request.AddParameter(FlickrParameterType.PermAddMeta, metaDataPerms);
            Send(request);            
        }
	    
        public void setTags(string photoId, params string[] tags)
        {
            FlickrRequest request = CreateRequest();
            request.AddParameter(FlickrParameterType.PhotoId, photoId);
            request.AddParameter(FlickrParameterType.Tags, tags);
            
            Send(request);
        }
	    
	    static public class Notes
	    {
	        static public void add(string photoId, int X, int Y, int width, int height, string noteText)
	        {
                FlickrRequest request = new FlickrRequest("flickr.photos.notes.add");
	            request.AddParameter(FlickrParameterType.NoteX, X);
	            request.AddParameter(FlickrParameterType.NoteY, Y);
	            request.AddParameter(FlickrParameterType.NoteW, width);
	            request.AddParameter(FlickrParameterType.NoteH, height);
	            request.AddParameter(FlickrParameterType.NoteText, noteText);

                request.Send(Flickr.Connection);
	        }

	        static public void delete(string noteId)
            {
                FlickrRequest request = new FlickrRequest("flickr.photos.notes.delete");
                request.AddParameter(FlickrParameterType.NoteId, noteId);

                request.Send(Flickr.Connection);
            }

            static public void edit(string photoId, int X, int Y, int width, int height, string noteText)
            {
                FlickrRequest request = new FlickrRequest("flickr.photos.notes.edit");
                request.AddParameter(FlickrParameterType.NoteX, X);
                request.AddParameter(FlickrParameterType.NoteY, Y);
                request.AddParameter(FlickrParameterType.NoteW, width);
                request.AddParameter(FlickrParameterType.NoteH, height);
                request.AddParameter(FlickrParameterType.NoteText, noteText);

                request.Send(Flickr.Connection);
            }
	    }
	    
	    public static class Licenses
	    {
	        static public api.Licenses getInfo()
	        {
                FlickrRequest request = new FlickrRequest("flickr.photos.licenses.getInfo");
                return request.Send(Flickr.Connection).Licenses;
	        }

            static public void setLicense(string photoId, string licenseId)
            {
                FlickrRequest request = new FlickrRequest("flickr.photos.licenses.setLicense");
                request.AddParameter(FlickrParameterType.PhotoId, photoId);
                request.AddParameter(FlickrParameterType.LicenseId, licenseId);
                request.Send(Flickr.Connection);
            }
	    }
	    
//	    public static class Comments
//	    {
//	        static api.Comments getList(string photoId)
//	        {
//                FlickrRequest request = new FlickrRequest("flickr.photos.coments.getList");
//                request.AddParameter(FlickrParameterType.PhotoId, photoId);
//
//                request.Send(Flickr.Connection).;
//	        }
//	    }
	}
}